
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Django 2.2 release notes &#8212; Django 2.2.12.dev20200304094918 documentation</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Django 2.1.15 release notes" href="2.1.15.html" />
    <link rel="prev" title="Django 2.2.1 release notes" href="2.2.1.html" />



 
<script type="text/javascript" src="../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../index.html">Django 2.2.12.dev20200304094918 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../index.html">Home</a>  |
        <a title="Table of contents" href="../contents.html">Table of contents</a>  |
        <a title="Global index" href="../genindex.html">Index</a>  |
        <a title="Module index" href="../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="2.2.1.html" title="Django 2.2.1 release notes">previous</a>
     |
    <a href="index.html" title="Release notes" accesskey="U">up</a>
   |
    <a href="2.1.15.html" title="Django 2.1.15 release notes">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="releases-2.2">
            
  <div class="section" id="s-django-2-2-release-notes">
<span id="django-2-2-release-notes"></span><h1>Django 2.2 release notes<a class="headerlink" href="#django-2-2-release-notes" title="Permalink to this headline">¶</a></h1>
<p><em>April 1, 2019</em></p>
<p>Welcome to Django 2.2!</p>
<p>These release notes cover the <a class="reference internal" href="#whats-new-2-2"><span class="std std-ref">new features</span></a>, as well as
some <a class="reference internal" href="#backwards-incompatible-2-2"><span class="std std-ref">backwards incompatible changes</span></a> you’ll
want to be aware of when upgrading from Django 2.1 or earlier. We’ve
<a class="reference internal" href="#deprecated-features-2-2"><span class="std std-ref">begun the deprecation process for some features</span></a>.</p>
<p>See the <a class="reference internal" href="../howto/upgrade-version.html"><span class="doc">Upgrading Django to a newer version</span></a> guide if you’re updating an existing
project.</p>
<p>Django 2.2 is designated as a <a class="reference internal" href="../internals/release-process.html#term-long-term-support-release"><span class="xref std std-term">long-term support release</span></a>. It will
receive security updates for at least three years after its release. Support
for the previous LTS, Django 1.11, will end in April 2020.</p>
<div class="section" id="s-python-compatibility">
<span id="python-compatibility"></span><h2>Python compatibility<a class="headerlink" href="#python-compatibility" title="Permalink to this headline">¶</a></h2>
<p>Django 2.2 supports Python 3.5, 3.6, 3.7, and 3.8 (as of 2.2.8). We
<strong>highly recommend</strong> and only officially support the latest release of each
series.</p>
</div>
<div class="section" id="s-what-s-new-in-django-2-2">
<span id="s-whats-new-2-2"></span><span id="what-s-new-in-django-2-2"></span><span id="whats-new-2-2"></span><h2>What’s new in Django 2.2<a class="headerlink" href="#what-s-new-in-django-2-2" title="Permalink to this headline">¶</a></h2>
<div class="section" id="s-constraints">
<span id="constraints"></span><h3>Constraints<a class="headerlink" href="#constraints" title="Permalink to this headline">¶</a></h3>
<p>The new <a class="reference internal" href="../ref/models/constraints.html#django.db.models.CheckConstraint" title="django.db.models.CheckConstraint"><code class="xref py py-class docutils literal notranslate"><span class="pre">CheckConstraint</span></code></a> and
<a class="reference internal" href="../ref/models/constraints.html#django.db.models.UniqueConstraint" title="django.db.models.UniqueConstraint"><code class="xref py py-class docutils literal notranslate"><span class="pre">UniqueConstraint</span></code></a> classes enable adding custom
database constraints. Constraints are added to models using the
<a class="reference internal" href="../ref/models/options.html#django.db.models.Options.constraints" title="django.db.models.Options.constraints"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Meta.constraints</span></code></a> option.</p>
</div>
<div class="section" id="s-minor-features">
<span id="minor-features"></span><h3>Minor features<a class="headerlink" href="#minor-features" title="Permalink to this headline">¶</a></h3>
<div class="section" id="s-django-contrib-admin">
<span id="django-contrib-admin"></span><h4><a class="reference internal" href="../ref/contrib/admin/index.html#module-django.contrib.admin" title="django.contrib.admin: Django's admin site."><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.admin</span></code></a><a class="headerlink" href="#django-contrib-admin" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added a CSS class to the column headers of
<a class="reference internal" href="../ref/contrib/admin/index.html#django.contrib.admin.TabularInline" title="django.contrib.admin.TabularInline"><code class="xref py py-class docutils literal notranslate"><span class="pre">TabularInline</span></code></a>.</li>
</ul>
</div>
<div class="section" id="s-django-contrib-auth">
<span id="django-contrib-auth"></span><h4><a class="reference internal" href="../topics/auth/index.html#module-django.contrib.auth" title="django.contrib.auth: Django's authentication framework."><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.auth</span></code></a><a class="headerlink" href="#django-contrib-auth" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The <code class="docutils literal notranslate"><span class="pre">HttpRequest</span></code> is now passed as the first positional argument to
<a class="reference internal" href="../ref/contrib/auth.html#django.contrib.auth.backends.RemoteUserBackend.configure_user" title="django.contrib.auth.backends.RemoteUserBackend.configure_user"><code class="xref py py-meth docutils literal notranslate"><span class="pre">RemoteUserBackend.configure_user()</span></code></a>, if it accepts it.</li>
</ul>
</div>
<div class="section" id="s-django-contrib-gis">
<span id="django-contrib-gis"></span><h4><a class="reference internal" href="../ref/contrib/gis/index.html#module-django.contrib.gis" title="django.contrib.gis: Geographic Information System (GIS) extensions for Django"><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.gis</span></code></a><a class="headerlink" href="#django-contrib-gis" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added Oracle support for the
<a class="reference internal" href="../ref/contrib/gis/functions.html#django.contrib.gis.db.models.functions.Envelope" title="django.contrib.gis.db.models.functions.Envelope"><code class="xref py py-class docutils literal notranslate"><span class="pre">Envelope</span></code></a> function.</li>
<li>Added SpatiaLite support for the <a class="reference internal" href="../ref/contrib/gis/geoquerysets.html#std:fieldlookup-coveredby"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">coveredby</span></code></a> and <a class="reference internal" href="../ref/contrib/gis/geoquerysets.html#std:fieldlookup-covers"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">covers</span></code></a>
lookups.</li>
</ul>
</div>
<div class="section" id="s-django-contrib-postgres">
<span id="django-contrib-postgres"></span><h4><a class="reference internal" href="../ref/contrib/postgres/index.html#module-django.contrib.postgres" title="django.contrib.postgres: PostgreSQL-specific fields and features"><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.postgres</span></code></a><a class="headerlink" href="#django-contrib-postgres" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <code class="docutils literal notranslate"><span class="pre">ordering</span></code> argument for
<a class="reference internal" href="../ref/contrib/postgres/aggregates.html#django.contrib.postgres.aggregates.ArrayAgg" title="django.contrib.postgres.aggregates.ArrayAgg"><code class="xref py py-class docutils literal notranslate"><span class="pre">ArrayAgg</span></code></a> and
<a class="reference internal" href="../ref/contrib/postgres/aggregates.html#django.contrib.postgres.aggregates.StringAgg" title="django.contrib.postgres.aggregates.StringAgg"><code class="xref py py-class docutils literal notranslate"><span class="pre">StringAgg</span></code></a> determines the
ordering of the aggregated elements.</li>
<li>The new <a class="reference internal" href="../ref/contrib/postgres/indexes.html#django.contrib.postgres.indexes.BTreeIndex" title="django.contrib.postgres.indexes.BTreeIndex"><code class="xref py py-class docutils literal notranslate"><span class="pre">BTreeIndex</span></code></a>,
<a class="reference internal" href="../ref/contrib/postgres/indexes.html#django.contrib.postgres.indexes.HashIndex" title="django.contrib.postgres.indexes.HashIndex"><code class="xref py py-class docutils literal notranslate"><span class="pre">HashIndex</span></code></a> and
<a class="reference internal" href="../ref/contrib/postgres/indexes.html#django.contrib.postgres.indexes.SpGistIndex" title="django.contrib.postgres.indexes.SpGistIndex"><code class="xref py py-class docutils literal notranslate"><span class="pre">SpGistIndex</span></code></a> classes allow
creating <code class="docutils literal notranslate"><span class="pre">B-Tree</span></code>, <code class="docutils literal notranslate"><span class="pre">hash</span></code>, and <code class="docutils literal notranslate"><span class="pre">SP-GiST</span></code> indexes in the database.</li>
<li><a class="reference internal" href="../ref/contrib/postgres/indexes.html#django.contrib.postgres.indexes.BrinIndex" title="django.contrib.postgres.indexes.BrinIndex"><code class="xref py py-class docutils literal notranslate"><span class="pre">BrinIndex</span></code></a> now has the
<code class="docutils literal notranslate"><span class="pre">autosummarize</span></code> parameter.</li>
<li>The new <code class="docutils literal notranslate"><span class="pre">search_type</span></code> parameter of
<a class="reference internal" href="../ref/contrib/postgres/search.html#django.contrib.postgres.search.SearchQuery" title="django.contrib.postgres.search.SearchQuery"><code class="xref py py-class docutils literal notranslate"><span class="pre">SearchQuery</span></code></a> allows searching for
a phrase or raw expression.</li>
</ul>
</div>
<div class="section" id="s-django-contrib-staticfiles">
<span id="django-contrib-staticfiles"></span><h4><a class="reference internal" href="../ref/contrib/staticfiles.html#module-django.contrib.staticfiles" title="django.contrib.staticfiles: An app for handling static files."><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.staticfiles</span></code></a><a class="headerlink" href="#django-contrib-staticfiles" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added path matching to the <a class="reference internal" href="../ref/contrib/staticfiles.html#cmdoption-collectstatic-ignore"><code class="xref std std-option docutils literal notranslate"><span class="pre">collectstatic</span> <span class="pre">--ignore</span></code></a> option so that
patterns like <code class="docutils literal notranslate"><span class="pre">/vendor/*.js</span></code> can be used.</li>
</ul>
</div>
<div class="section" id="s-database-backends">
<span id="database-backends"></span><h4>Database backends<a class="headerlink" href="#database-backends" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added result streaming for <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.iterator" title="django.db.models.query.QuerySet.iterator"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.iterator()</span></code></a> on SQLite.</li>
</ul>
</div>
<div class="section" id="s-generic-views">
<span id="generic-views"></span><h4>Generic Views<a class="headerlink" href="#generic-views" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <a class="reference internal" href="../ref/class-based-views/base.html#django.views.generic.base.View.setup" title="django.views.generic.base.View.setup"><code class="xref py py-meth docutils literal notranslate"><span class="pre">View.setup</span></code></a> hook
initializes view attributes before calling
<a class="reference internal" href="../ref/class-based-views/base.html#django.views.generic.base.View.dispatch" title="django.views.generic.base.View.dispatch"><code class="xref py py-meth docutils literal notranslate"><span class="pre">dispatch()</span></code></a>. It allows mixins to setup
instance attributes for reuse in child classes.</li>
</ul>
</div>
<div class="section" id="s-internationalization">
<span id="internationalization"></span><h4>Internationalization<a class="headerlink" href="#internationalization" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added support and translations for the Armenian language.</li>
</ul>
</div>
<div class="section" id="s-management-commands">
<span id="management-commands"></span><h4>Management Commands<a class="headerlink" href="#management-commands" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <a class="reference internal" href="../ref/django-admin.html#cmdoption-force-color"><code class="xref std std-option docutils literal notranslate"><span class="pre">--force-color</span></code></a> option forces colorization of the command
output.</li>
<li><a class="reference internal" href="../ref/django-admin.html#django-admin-inspectdb"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">inspectdb</span></code></a> now creates models for foreign tables on PostgreSQL.</li>
<li><a class="reference internal" href="../ref/django-admin.html#cmdoption-inspectdb-include-views"><code class="xref std std-option docutils literal notranslate"><span class="pre">inspectdb</span> <span class="pre">--include-views</span></code></a> now creates models for materialized views
on Oracle and PostgreSQL.</li>
<li>The new <a class="reference internal" href="../ref/django-admin.html#cmdoption-inspectdb-include-partitions"><code class="xref std std-option docutils literal notranslate"><span class="pre">inspectdb</span> <span class="pre">--include-partitions</span></code></a> option allows creating
models for partition tables on PostgreSQL. In older versions, models are
created child tables instead the parent.</li>
<li><a class="reference internal" href="../ref/django-admin.html#django-admin-inspectdb"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">inspectdb</span></code></a> now introspects <a class="reference internal" href="../ref/models/fields.html#django.db.models.DurationField" title="django.db.models.DurationField"><code class="xref py py-class docutils literal notranslate"><span class="pre">DurationField</span></code></a>
for Oracle and PostgreSQL, and <a class="reference internal" href="../ref/models/fields.html#django.db.models.AutoField" title="django.db.models.AutoField"><code class="xref py py-class docutils literal notranslate"><span class="pre">AutoField</span></code></a> for
SQLite.</li>
<li>On Oracle, <a class="reference internal" href="../ref/django-admin.html#django-admin-dbshell"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">dbshell</span></code></a> is wrapped with <code class="docutils literal notranslate"><span class="pre">rlwrap</span></code>, if available.
<code class="docutils literal notranslate"><span class="pre">rlwrap</span></code> provides a command history and editing of keyboard input.</li>
<li>The new <a class="reference internal" href="../ref/django-admin.html#cmdoption-makemigrations-no-header"><code class="xref std std-option docutils literal notranslate"><span class="pre">makemigrations</span> <span class="pre">--no-header</span></code></a> option avoids writing header
comments in generated migration file(s). This option is also available for
<a class="reference internal" href="../ref/django-admin.html#django-admin-squashmigrations"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">squashmigrations</span></code></a>.</li>
<li><a class="reference internal" href="../ref/django-admin.html#django-admin-runserver"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">runserver</span></code></a> can now use <a class="reference external" href="https://facebook.github.io/watchman/">Watchman</a> to improve the performance of
watching a large number of files for changes.</li>
</ul>
</div>
<div class="section" id="s-migrations">
<span id="migrations"></span><h4>Migrations<a class="headerlink" href="#migrations" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <a class="reference internal" href="../ref/django-admin.html#cmdoption-migrate-plan"><code class="xref std std-option docutils literal notranslate"><span class="pre">migrate</span> <span class="pre">--plan</span></code></a> option prints the list of migration
operations that will be performed.</li>
<li><code class="docutils literal notranslate"><span class="pre">NoneType</span></code> can now be serialized in migrations.</li>
<li>You can now <a class="reference internal" href="../topics/migrations.html#custom-migration-serializers"><span class="std std-ref">register custom serializers</span></a>
for migrations.</li>
</ul>
</div>
<div class="section" id="s-models">
<span id="models"></span><h4>Models<a class="headerlink" href="#models" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added support for PostgreSQL operator classes (<a class="reference internal" href="../ref/models/indexes.html#django.db.models.Index.opclasses" title="django.db.models.Index.opclasses"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Index.opclasses</span></code></a>).</li>
<li>Added support for partial indexes (<a class="reference internal" href="../ref/models/indexes.html#django.db.models.Index.condition" title="django.db.models.Index.condition"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Index.condition</span></code></a>).</li>
<li>Added the <a class="reference internal" href="../ref/models/database-functions.html#django.db.models.functions.NullIf" title="django.db.models.functions.NullIf"><code class="xref py py-class docutils literal notranslate"><span class="pre">NullIf</span></code></a> and
<a class="reference internal" href="../ref/models/database-functions.html#django.db.models.functions.Reverse" title="django.db.models.functions.Reverse"><code class="xref py py-class docutils literal notranslate"><span class="pre">Reverse</span></code></a> database functions, as well as
many <a class="reference internal" href="../ref/models/database-functions.html#math-functions"><span class="std std-ref">math database functions</span></a>.</li>
<li>Setting the new <code class="docutils literal notranslate"><span class="pre">ignore_conflicts</span></code> parameter of
<a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_create" title="django.db.models.query.QuerySet.bulk_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.bulk_create()</span></code></a> to <code class="docutils literal notranslate"><span class="pre">True</span></code> tells the database to ignore
failure to insert rows that fail uniqueness constraints or other checks.</li>
<li>The new <a class="reference internal" href="../ref/models/database-functions.html#django.db.models.functions.ExtractIsoYear" title="django.db.models.functions.ExtractIsoYear"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExtractIsoYear</span></code></a> function extracts
ISO-8601 week-numbering years from <a class="reference internal" href="../ref/models/fields.html#django.db.models.DateField" title="django.db.models.DateField"><code class="xref py py-class docutils literal notranslate"><span class="pre">DateField</span></code></a> and
<a class="reference internal" href="../ref/models/fields.html#django.db.models.DateTimeField" title="django.db.models.DateTimeField"><code class="xref py py-class docutils literal notranslate"><span class="pre">DateTimeField</span></code></a>, and the new <a class="reference internal" href="../ref/models/querysets.html#std:fieldlookup-iso_year"><code class="xref std std-lookup docutils literal notranslate"><span class="pre">iso_year</span></code></a>
lookup allows querying by an ISO-8601 week-numbering year.</li>
<li>The new <a class="reference internal" href="../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_update" title="django.db.models.query.QuerySet.bulk_update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.bulk_update()</span></code></a> method allows efficiently updating
specific fields on multiple model instances.</li>
<li>Django no longer always starts a transaction when a single query is being
performed, such as <code class="docutils literal notranslate"><span class="pre">Model.save()</span></code>, <code class="docutils literal notranslate"><span class="pre">QuerySet.update()</span></code>, and
<code class="docutils literal notranslate"><span class="pre">Model.delete()</span></code>. This improves the performance of autocommit by reducing
the number of database round trips.</li>
<li>Added SQLite support for the <a class="reference internal" href="../ref/models/querysets.html#django.db.models.StdDev" title="django.db.models.StdDev"><code class="xref py py-class docutils literal notranslate"><span class="pre">StdDev</span></code></a> and
<a class="reference internal" href="../ref/models/querysets.html#django.db.models.Variance" title="django.db.models.Variance"><code class="xref py py-class docutils literal notranslate"><span class="pre">Variance</span></code></a> functions.</li>
<li>The handling of <code class="docutils literal notranslate"><span class="pre">DISTINCT</span></code> aggregation is added to the
<a class="reference internal" href="../ref/models/expressions.html#django.db.models.Aggregate" title="django.db.models.Aggregate"><code class="xref py py-class docutils literal notranslate"><span class="pre">Aggregate</span></code></a> class. Adding <a class="reference internal" href="../ref/models/expressions.html#django.db.models.Aggregate.allow_distinct" title="django.db.models.Aggregate.allow_distinct"><code class="xref py py-attr docutils literal notranslate"><span class="pre">allow_distinct</span> <span class="pre">=</span>
<span class="pre">True</span></code></a> as a class attribute on
<code class="docutils literal notranslate"><span class="pre">Aggregate</span></code> subclasses allows a <code class="docutils literal notranslate"><span class="pre">distinct</span></code> keyword argument to be
specified on initialization to ensure that the aggregate function is only
called for each distinct value of <code class="docutils literal notranslate"><span class="pre">expressions</span></code>.</li>
<li>The <a class="reference internal" href="../ref/models/relations.html#django.db.models.fields.related.RelatedManager.add" title="django.db.models.fields.related.RelatedManager.add"><code class="xref py py-meth docutils literal notranslate"><span class="pre">RelatedManager.add()</span></code></a>, <a class="reference internal" href="../ref/models/relations.html#django.db.models.fields.related.RelatedManager.create" title="django.db.models.fields.related.RelatedManager.create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">create()</span></code></a>,
<a class="reference internal" href="../ref/models/relations.html#django.db.models.fields.related.RelatedManager.remove" title="django.db.models.fields.related.RelatedManager.remove"><code class="xref py py-meth docutils literal notranslate"><span class="pre">remove()</span></code></a>,  <a class="reference internal" href="../ref/models/relations.html#django.db.models.fields.related.RelatedManager.set" title="django.db.models.fields.related.RelatedManager.set"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set()</span></code></a>,
<code class="docutils literal notranslate"><span class="pre">get_or_create()</span></code>, and <code class="docutils literal notranslate"><span class="pre">update_or_create()</span></code> methods are now allowed on
many-to-many relationships with intermediate models. The new
<code class="docutils literal notranslate"><span class="pre">through_defaults</span></code> argument is used to specify values for new intermediate
model instance(s).</li>
</ul>
</div>
<div class="section" id="s-requests-and-responses">
<span id="requests-and-responses"></span><h4>Requests and Responses<a class="headerlink" href="#requests-and-responses" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>Added <a class="reference internal" href="../ref/request-response.html#django.http.HttpRequest.headers" title="django.http.HttpRequest.headers"><code class="xref py py-attr docutils literal notranslate"><span class="pre">HttpRequest.headers</span></code></a> to allow simple access to a request’s
headers.</li>
</ul>
</div>
<div class="section" id="s-serialization">
<span id="serialization"></span><h4>Serialization<a class="headerlink" href="#serialization" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>You can now deserialize data using natural keys containing <a class="reference internal" href="../topics/serialization.html#natural-keys-and-forward-references"><span class="std std-ref">forward
references</span></a> by passing
<code class="docutils literal notranslate"><span class="pre">handle_forward_references=True</span></code> to <code class="docutils literal notranslate"><span class="pre">serializers.deserialize()</span></code>.
Additionally, <a class="reference internal" href="../ref/django-admin.html#django-admin-loaddata"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">loaddata</span></code></a> handles forward references automatically.</li>
</ul>
</div>
<div class="section" id="s-tests">
<span id="tests"></span><h4>Tests<a class="headerlink" href="#tests" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <a class="reference internal" href="../topics/testing/tools.html#django.test.SimpleTestCase.assertURLEqual" title="django.test.SimpleTestCase.assertURLEqual"><code class="xref py py-meth docutils literal notranslate"><span class="pre">SimpleTestCase.assertURLEqual()</span></code></a> assertion checks for a given
URL, ignoring the ordering of the query string.
<a class="reference internal" href="../topics/testing/tools.html#django.test.SimpleTestCase.assertRedirects" title="django.test.SimpleTestCase.assertRedirects"><code class="xref py py-meth docutils literal notranslate"><span class="pre">assertRedirects()</span></code></a> uses the new assertion.</li>
<li>The test <a class="reference internal" href="../topics/testing/tools.html#django.test.Client" title="django.test.Client"><code class="xref py py-class docutils literal notranslate"><span class="pre">Client</span></code></a> now supports automatic JSON
serialization of list and tuple <code class="docutils literal notranslate"><span class="pre">data</span></code> when
<code class="docutils literal notranslate"><span class="pre">content_type='application/json'</span></code>.</li>
<li>The new <a class="reference internal" href="../ref/settings.html#std:setting-TEST_ORACLE_MANAGED_FILES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">ORACLE_MANAGED_FILES</span></code></a> test
database setting allows using Oracle Managed Files (OMF) tablespaces.</li>
<li>Deferrable database constraints are now checked at the end of each
<a class="reference internal" href="../topics/testing/tools.html#django.test.TestCase" title="django.test.TestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TestCase</span></code></a> test on SQLite 3.20+, just like on other
backends that support deferrable constraints. These checks aren’t implemented
for older versions of SQLite because they would require expensive table
introspection there.</li>
<li><a class="reference internal" href="../topics/testing/advanced.html#django.test.runner.DiscoverRunner" title="django.test.runner.DiscoverRunner"><code class="xref py py-class docutils literal notranslate"><span class="pre">DiscoverRunner</span></code></a> now skips the setup of databases
not <a class="reference internal" href="../topics/testing/tools.html#testing-multi-db"><span class="std std-ref">referenced by tests</span></a>.</li>
</ul>
</div>
<div class="section" id="s-urls">
<span id="urls"></span><h4>URLs<a class="headerlink" href="#urls" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li>The new <a class="reference internal" href="../ref/urlresolvers.html#django.urls.ResolverMatch.route" title="django.urls.ResolverMatch.route"><code class="xref py py-attr docutils literal notranslate"><span class="pre">ResolverMatch.route</span></code></a> attribute stores the route of the
matching URL pattern.</li>
</ul>
</div>
<div class="section" id="s-validators">
<span id="validators"></span><h4>Validators<a class="headerlink" href="#validators" title="Permalink to this headline">¶</a></h4>
<ul class="simple">
<li><a class="reference internal" href="../ref/validators.html#django.core.validators.MaxValueValidator" title="django.core.validators.MaxValueValidator"><code class="xref py py-class docutils literal notranslate"><span class="pre">MaxValueValidator</span></code></a>, <a class="reference internal" href="../ref/validators.html#django.core.validators.MinValueValidator" title="django.core.validators.MinValueValidator"><code class="xref py py-class docutils literal notranslate"><span class="pre">MinValueValidator</span></code></a>,
<a class="reference internal" href="../ref/validators.html#django.core.validators.MinLengthValidator" title="django.core.validators.MinLengthValidator"><code class="xref py py-class docutils literal notranslate"><span class="pre">MinLengthValidator</span></code></a>, and <a class="reference internal" href="../ref/validators.html#django.core.validators.MaxLengthValidator" title="django.core.validators.MaxLengthValidator"><code class="xref py py-class docutils literal notranslate"><span class="pre">MaxLengthValidator</span></code></a> now accept
a callable <code class="docutils literal notranslate"><span class="pre">limit_value</span></code>.</li>
</ul>
</div>
</div>
</div>
<div class="section" id="s-backwards-incompatible-changes-in-2-2">
<span id="s-backwards-incompatible-2-2"></span><span id="backwards-incompatible-changes-in-2-2"></span><span id="backwards-incompatible-2-2"></span><h2>Backwards incompatible changes in 2.2<a class="headerlink" href="#backwards-incompatible-changes-in-2-2" title="Permalink to this headline">¶</a></h2>
<div class="section" id="s-database-backend-api">
<span id="database-backend-api"></span><h3>Database backend API<a class="headerlink" href="#database-backend-api" title="Permalink to this headline">¶</a></h3>
<p>This section describes changes that may be needed in third-party database
backends.</p>
<ul class="simple">
<li>Third-party database backends must implement support for table check
constraints or set <code class="docutils literal notranslate"><span class="pre">DatabaseFeatures.supports_table_check_constraints</span></code> to
<code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li>Third party database backends must implement support for ignoring
constraints or uniqueness errors while inserting or set
<code class="docutils literal notranslate"><span class="pre">DatabaseFeatures.supports_ignore_conflicts</span></code> to <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li>Third party database backends must implement introspection for
<code class="docutils literal notranslate"><span class="pre">DurationField</span></code> or set <code class="docutils literal notranslate"><span class="pre">DatabaseFeatures.can_introspect_duration_field</span></code>
to <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li><code class="docutils literal notranslate"><span class="pre">DatabaseFeatures.uses_savepoints</span></code> now defaults to <code class="docutils literal notranslate"><span class="pre">True</span></code>.</li>
<li>Third party database backends must implement support for partial indexes or
set <code class="docutils literal notranslate"><span class="pre">DatabaseFeatures.supports_partial_indexes</span></code> to <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li><code class="docutils literal notranslate"><span class="pre">DatabaseIntrospection.table_name_converter()</span></code> and
<code class="docutils literal notranslate"><span class="pre">column_name_converter()</span></code> are removed. Third party database backends may
need to instead implement <code class="docutils literal notranslate"><span class="pre">DatabaseIntrospection.identifier_converter()</span></code>.
In that case, the constraint names that
<code class="docutils literal notranslate"><span class="pre">DatabaseIntrospection.get_constraints()</span></code> returns must be normalized by
<code class="docutils literal notranslate"><span class="pre">identifier_converter()</span></code>.</li>
<li>SQL generation for indexes is moved from <a class="reference internal" href="../ref/models/indexes.html#django.db.models.Index" title="django.db.models.Index"><code class="xref py py-class docutils literal notranslate"><span class="pre">Index</span></code></a> to
<code class="docutils literal notranslate"><span class="pre">SchemaEditor</span></code> and these <code class="docutils literal notranslate"><span class="pre">SchemaEditor</span></code> methods are added:<ul>
<li><code class="docutils literal notranslate"><span class="pre">_create_primary_key_sql()</span></code> and <code class="docutils literal notranslate"><span class="pre">_delete_primary_key_sql()</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">_delete_index_sql()</span></code> (to pair with <code class="docutils literal notranslate"><span class="pre">_create_index_sql()</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">_delete_unique_sql</span></code> (to pair with <code class="docutils literal notranslate"><span class="pre">_create_unique_sql()</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">_delete_fk_sql()</span></code> (to pair with <code class="docutils literal notranslate"><span class="pre">_create_fk_sql()</span></code>)</li>
<li><code class="docutils literal notranslate"><span class="pre">_create_check_sql()</span></code> and <code class="docutils literal notranslate"><span class="pre">_delete_check_sql()</span></code></li>
</ul>
</li>
<li>The third argument of <code class="docutils literal notranslate"><span class="pre">DatabaseWrapper.__init__()</span></code>,
<code class="docutils literal notranslate"><span class="pre">allow_thread_sharing</span></code>, is removed.</li>
</ul>
</div>
<div class="section" id="s-admin-actions-are-no-longer-collected-from-base-modeladmin-classes">
<span id="admin-actions-are-no-longer-collected-from-base-modeladmin-classes"></span><h3>Admin actions are no longer collected from base <code class="docutils literal notranslate"><span class="pre">ModelAdmin</span></code> classes<a class="headerlink" href="#admin-actions-are-no-longer-collected-from-base-modeladmin-classes" title="Permalink to this headline">¶</a></h3>
<p>For example, in older versions of Django:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.contrib</span> <span class="k">import</span> <span class="n">admin</span>

<span class="k">class</span> <span class="nc">BaseAdmin</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">ModelAdmin</span><span class="p">):</span>
    <span class="n">actions</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;a&#39;</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">SubAdmin</span><span class="p">(</span><span class="n">BaseAdmin</span><span class="p">):</span>
    <span class="n">actions</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;b&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">SubAdmin</span></code> would have actions <code class="docutils literal notranslate"><span class="pre">'a'</span></code> and <code class="docutils literal notranslate"><span class="pre">'b'</span></code>.</p>
<p>Now <code class="docutils literal notranslate"><span class="pre">actions</span></code> follows standard Python inheritance. To get the same result as
before:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SubAdmin</span><span class="p">(</span><span class="n">BaseAdmin</span><span class="p">):</span>
    <span class="n">actions</span> <span class="o">=</span> <span class="n">BaseAdmin</span><span class="o">.</span><span class="n">actions</span> <span class="o">+</span> <span class="p">[</span><span class="s1">&#39;b&#39;</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="s-id1">
<span id="id1"></span><h3><a class="reference internal" href="../ref/contrib/gis/index.html#module-django.contrib.gis" title="django.contrib.gis: Geographic Information System (GIS) extensions for Django"><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.contrib.gis</span></code></a><a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li>Support for GDAL 1.9 and 1.10 is dropped.</li>
</ul>
</div>
<div class="section" id="s-transactiontestcase-serialized-data-loading">
<span id="transactiontestcase-serialized-data-loading"></span><h3><code class="docutils literal notranslate"><span class="pre">TransactionTestCase</span></code> serialized data loading<a class="headerlink" href="#transactiontestcase-serialized-data-loading" title="Permalink to this headline">¶</a></h3>
<p>Initial data migrations are now loaded in
<a class="reference internal" href="../topics/testing/tools.html#django.test.TransactionTestCase" title="django.test.TransactionTestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TransactionTestCase</span></code></a> at the end of the test, after the
database flush. In older versions, this data was loaded at the beginning of the
test, but this prevents the <a class="reference internal" href="../ref/django-admin.html#cmdoption-test-keepdb"><code class="xref std std-option docutils literal notranslate"><span class="pre">test</span> <span class="pre">--keepdb</span></code></a> option from working
properly (the database was empty at the end of the whole test suite). This
change shouldn’t have an impact on your tests unless you’ve customized
<a class="reference internal" href="../topics/testing/tools.html#django.test.TransactionTestCase" title="django.test.TransactionTestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TransactionTestCase</span></code></a>’s internals.</p>
</div>
<div class="section" id="s-sqlparse-is-required-dependency">
<span id="sqlparse-is-required-dependency"></span><h3><code class="docutils literal notranslate"><span class="pre">sqlparse</span></code> is required dependency<a class="headerlink" href="#sqlparse-is-required-dependency" title="Permalink to this headline">¶</a></h3>
<p>To simplify a few parts of Django’s database handling, <a class="reference external" href="https://pypi.org/project/sqlparse/">sqlparse</a> is now a required dependency. It’s
automatically installed along with Django.</p>
</div>
<div class="section" id="s-cached-property-aliases">
<span id="cached-property-aliases"></span><h3><code class="docutils literal notranslate"><span class="pre">cached_property</span></code> aliases<a class="headerlink" href="#cached-property-aliases" title="Permalink to this headline">¶</a></h3>
<p>In usage like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.utils.functional</span> <span class="k">import</span> <span class="n">cached_property</span>

<span class="k">class</span> <span class="nc">A</span><span class="p">:</span>

    <span class="nd">@cached_property</span>
    <span class="k">def</span> <span class="nf">base</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="o">...</span>

    <span class="n">alias</span> <span class="o">=</span> <span class="n">base</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">alias</span></code> is not cached. Where the problem can be detected (Python 3.6 and
later), such usage now raises <code class="docutils literal notranslate"><span class="pre">TypeError:</span> <span class="pre">Cannot</span> <span class="pre">assign</span> <span class="pre">the</span> <span class="pre">same</span>
<span class="pre">cached_property</span> <span class="pre">to</span> <span class="pre">two</span> <span class="pre">different</span> <span class="pre">names</span> <span class="pre">('base'</span> <span class="pre">and</span> <span class="pre">'alias').</span></code></p>
<p>Use this instead:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">operator</span>

<span class="k">class</span> <span class="nc">A</span><span class="p">:</span>

    <span class="o">...</span>

    <span class="n">alias</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">attrgetter</span><span class="p">(</span><span class="s1">&#39;base&#39;</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="section" id="s-permissions-for-proxy-models">
<span id="permissions-for-proxy-models"></span><h3>Permissions for proxy models<a class="headerlink" href="#permissions-for-proxy-models" title="Permalink to this headline">¶</a></h3>
<p><a class="reference internal" href="../topics/auth/default.html#proxy-models-permissions-topic"><span class="std std-ref">Permissions for proxy models</span></a> are now
created using the content type of the proxy model rather than the content type
of the concrete model. A migration will update existing permissions when you
run <a class="reference internal" href="../ref/django-admin.html#django-admin-migrate"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">migrate</span></code></a>.</p>
<p>In the admin, the change is transparent for proxy models having the same
<code class="docutils literal notranslate"><span class="pre">app_label</span></code> as their concrete model. However, in older versions, users with
permissions for a proxy model with a <em>different</em> <code class="docutils literal notranslate"><span class="pre">app_label</span></code> than its
concrete model couldn’t access the model in the admin. That’s now fixed, but
you might want to audit the permissions assignments for such proxy models
(<code class="docutils literal notranslate"><span class="pre">[add|view|change|delete]_myproxy</span></code>) prior to upgrading to ensure the new
access is appropriate.</p>
<p>Finally, proxy model permission strings must be updated to use their own
<code class="docutils literal notranslate"><span class="pre">app_label</span></code>. For example, for <code class="docutils literal notranslate"><span class="pre">app.MyProxyModel</span></code> inheriting from
<code class="docutils literal notranslate"><span class="pre">other_app.ConcreteModel</span></code>, update
<code class="docutils literal notranslate"><span class="pre">user.has_perm('other_app.add_myproxymodel')</span></code> to
<code class="docutils literal notranslate"><span class="pre">user.has_perm('app.add_myproxymodel')</span></code>.</p>
</div>
<div class="section" id="s-merging-of-form-media-assets">
<span id="merging-of-form-media-assets"></span><h3>Merging of form <code class="docutils literal notranslate"><span class="pre">Media</span></code> assets<a class="headerlink" href="#merging-of-form-media-assets" title="Permalink to this headline">¶</a></h3>
<p>Form <code class="docutils literal notranslate"><span class="pre">Media</span></code> assets are now merged using a topological sort algorithm, as the
old pairwise merging algorithm is insufficient for some cases. CSS and
JavaScript files which don’t include their dependencies may now be sorted
incorrectly (where the old algorithm produced results correctly by
coincidence).</p>
<p>Audit all <code class="docutils literal notranslate"><span class="pre">Media</span></code> classes for any missing dependencies. For example,
widgets depending on <code class="docutils literal notranslate"><span class="pre">django.jQuery</span></code> must specify
<code class="docutils literal notranslate"><span class="pre">js=['admin/js/jquery.init.js',</span> <span class="pre">...]</span></code> when <a class="reference internal" href="../topics/forms/media.html#assets-as-a-static-definition"><span class="std std-ref">declaring form media assets</span></a>.</p>
</div>
<div class="section" id="s-miscellaneous">
<span id="miscellaneous"></span><h3>Miscellaneous<a class="headerlink" href="#miscellaneous" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li>To improve readability, the <code class="docutils literal notranslate"><span class="pre">UUIDField</span></code> form field now displays values with
dashes, e.g. <code class="docutils literal notranslate"><span class="pre">550e8400-e29b-41d4-a716-446655440000</span></code> instead of
<code class="docutils literal notranslate"><span class="pre">550e8400e29b41d4a716446655440000</span></code>.</li>
<li>On SQLite, <code class="docutils literal notranslate"><span class="pre">PositiveIntegerField</span></code> and <code class="docutils literal notranslate"><span class="pre">PositiveSmallIntegerField</span></code> now
include a check constraint to prevent negative values in the database. If you
have existing invalid data and run a migration that recreates a table, you’ll
see <code class="docutils literal notranslate"><span class="pre">CHECK</span> <span class="pre">constraint</span> <span class="pre">failed</span></code>.</li>
<li>For consistency with WSGI servers, the test client now sets the
<code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> header to a string rather than an integer.</li>
<li>The return value of <a class="reference internal" href="../ref/utils.html#django.utils.text.slugify" title="django.utils.text.slugify"><code class="xref py py-func docutils literal notranslate"><span class="pre">django.utils.text.slugify()</span></code></a> is no longer marked as
HTML safe.</li>
<li>The default truncation character used by the <a class="reference internal" href="../ref/templates/builtins.html#std:templatefilter-urlizetrunc"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">urlizetrunc</span></code></a>,
<a class="reference internal" href="../ref/templates/builtins.html#std:templatefilter-truncatechars"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">truncatechars</span></code></a>, <a class="reference internal" href="../ref/templates/builtins.html#std:templatefilter-truncatechars_html"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">truncatechars_html</span></code></a>,
<a class="reference internal" href="../ref/templates/builtins.html#std:templatefilter-truncatewords"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">truncatewords</span></code></a>, and <a class="reference internal" href="../ref/templates/builtins.html#std:templatefilter-truncatewords_html"><code class="xref std std-tfilter docutils literal notranslate"><span class="pre">truncatewords_html</span></code></a> template filters
is now the real ellipsis character (<code class="docutils literal notranslate"><span class="pre">…</span></code>) instead of 3 dots. You may have to
adapt some test output comparisons.</li>
<li>Support for bytestring paths in the template filesystem loader is removed.</li>
<li><a class="reference internal" href="../ref/utils.html#django.utils.http.urlsafe_base64_encode" title="django.utils.http.urlsafe_base64_encode"><code class="xref py py-func docutils literal notranslate"><span class="pre">django.utils.http.urlsafe_base64_encode()</span></code></a> now returns a string instead
of a bytestring, and <a class="reference internal" href="../ref/utils.html#django.utils.http.urlsafe_base64_decode" title="django.utils.http.urlsafe_base64_decode"><code class="xref py py-func docutils literal notranslate"><span class="pre">django.utils.http.urlsafe_base64_decode()</span></code></a> may no
longer be passed a bytestring.</li>
<li>Support for <code class="docutils literal notranslate"><span class="pre">cx_Oracle</span></code> &lt; 6.0 is removed.</li>
<li>The minimum supported version of <code class="docutils literal notranslate"><span class="pre">mysqlclient</span></code> is increased from 1.3.7 to
1.3.13.</li>
<li>The minimum supported version of SQLite is increased from 3.7.15 to 3.8.3.</li>
<li>In an attempt to provide more semantic query data, <code class="docutils literal notranslate"><span class="pre">NullBooleanSelect</span></code> now
renders <code class="docutils literal notranslate"><span class="pre">&lt;option&gt;</span></code> values of <code class="docutils literal notranslate"><span class="pre">unknown</span></code>, <code class="docutils literal notranslate"><span class="pre">true</span></code>, and <code class="docutils literal notranslate"><span class="pre">false</span></code> instead
of <code class="docutils literal notranslate"><span class="pre">1</span></code>, <code class="docutils literal notranslate"><span class="pre">2</span></code>, and <code class="docutils literal notranslate"><span class="pre">3</span></code>. For backwards compatibility, the old values are
still accepted as data.</li>
<li><a class="reference internal" href="../ref/contrib/auth.html#django.contrib.auth.models.Group.name" title="django.contrib.auth.models.Group.name"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Group.name</span></code></a> <code class="docutils literal notranslate"><span class="pre">max_length</span></code>
is increased from 80 to 150 characters.</li>
<li>Tests that violate deferrable database constraints now error when run on
SQLite 3.20+, just like on other backends that support such constraints.</li>
<li>To catch usage mistakes, the test <a class="reference internal" href="../topics/testing/tools.html#django.test.Client" title="django.test.Client"><code class="xref py py-class docutils literal notranslate"><span class="pre">Client</span></code></a> and
<a class="reference internal" href="../ref/utils.html#django.utils.http.urlencode" title="django.utils.http.urlencode"><code class="xref py py-func docutils literal notranslate"><span class="pre">django.utils.http.urlencode()</span></code></a> now raise <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> if <code class="docutils literal notranslate"><span class="pre">None</span></code> is
passed as a value to encode because <code class="docutils literal notranslate"><span class="pre">None</span></code> can’t be encoded in GET and POST
data. Either pass an empty string or omit the value.</li>
<li>The <a class="reference internal" href="../ref/contrib/sitemaps.html#django-admin-ping_google"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">ping_google</span></code></a> management command now defaults to <code class="docutils literal notranslate"><span class="pre">https</span></code>
instead of <code class="docutils literal notranslate"><span class="pre">http</span></code> for the sitemap’s URL. If your site uses http, use the
new <a class="reference internal" href="../ref/contrib/sitemaps.html#cmdoption-ping-google-sitemap-uses-http"><code class="xref std std-option docutils literal notranslate"><span class="pre">ping_google</span> <span class="pre">--sitemap-uses-http</span></code></a> option. If you use the
<a class="reference internal" href="../ref/contrib/sitemaps.html#django.contrib.sitemaps.ping_google" title="django.contrib.sitemaps.ping_google"><code class="xref py py-func docutils literal notranslate"><span class="pre">ping_google()</span></code></a> function, set the new
<code class="docutils literal notranslate"><span class="pre">sitemap_uses_https</span></code> argument to <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li><a class="reference internal" href="../ref/django-admin.html#django-admin-runserver"><code class="xref std std-djadmin docutils literal notranslate"><span class="pre">runserver</span></code></a> no longer supports <cite>pyinotify</cite> (replaced by Watchman).</li>
<li>The <a class="reference internal" href="../ref/models/querysets.html#django.db.models.Avg" title="django.db.models.Avg"><code class="xref py py-class docutils literal notranslate"><span class="pre">Avg</span></code></a>, <a class="reference internal" href="../ref/models/querysets.html#django.db.models.StdDev" title="django.db.models.StdDev"><code class="xref py py-class docutils literal notranslate"><span class="pre">StdDev</span></code></a>, and
<a class="reference internal" href="../ref/models/querysets.html#django.db.models.Variance" title="django.db.models.Variance"><code class="xref py py-class docutils literal notranslate"><span class="pre">Variance</span></code></a> aggregate functions now return a
<code class="docutils literal notranslate"><span class="pre">Decimal</span></code> instead of a <code class="docutils literal notranslate"><span class="pre">float</span></code> when the input is <code class="docutils literal notranslate"><span class="pre">Decimal</span></code>.</li>
<li>Tests will fail on SQLite if apps without migrations have relations to apps
with migrations. This has been a documented restriction since migrations were
added in Django 1.7, but it fails more reliably now. You’ll see tests failing
with errors like <code class="docutils literal notranslate"><span class="pre">no</span> <span class="pre">such</span> <span class="pre">table:</span> <span class="pre">&lt;app_label&gt;_&lt;model&gt;</span></code>. This was observed
with several third-party apps that had models in tests without migrations.
You must add migrations for such models.</li>
<li>Providing an integer in the <code class="docutils literal notranslate"><span class="pre">key</span></code> argument of the <a class="reference internal" href="../topics/cache.html#django.core.caches.cache.delete" title="django.core.caches.cache.delete"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cache.delete()</span></code></a> or
<a class="reference internal" href="../topics/cache.html#django.core.caches.cache.get" title="django.core.caches.cache.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cache.get()</span></code></a> now raises <a class="reference external" href="https://docs.python.org/3/library/exceptions.html#ValueError" title="(in Python v3.8)"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>.</li>
</ul>
</div>
</div>
<div class="section" id="s-features-deprecated-in-2-2">
<span id="s-deprecated-features-2-2"></span><span id="features-deprecated-in-2-2"></span><span id="deprecated-features-2-2"></span><h2>Features deprecated in 2.2<a class="headerlink" href="#features-deprecated-in-2-2" title="Permalink to this headline">¶</a></h2>
<div class="section" id="s-model-meta-ordering-will-no-longer-affect-group-by-queries">
<span id="model-meta-ordering-will-no-longer-affect-group-by-queries"></span><h3>Model <code class="docutils literal notranslate"><span class="pre">Meta.ordering</span></code> will no longer affect <code class="docutils literal notranslate"><span class="pre">GROUP</span> <span class="pre">BY</span></code> queries<a class="headerlink" href="#model-meta-ordering-will-no-longer-affect-group-by-queries" title="Permalink to this headline">¶</a></h3>
<p>A model’s <code class="docutils literal notranslate"><span class="pre">Meta.ordering</span></code> affecting <code class="docutils literal notranslate"><span class="pre">GROUP</span> <span class="pre">BY</span></code> queries (such as
<code class="docutils literal notranslate"><span class="pre">.annotate().values()</span></code>) is a common source of confusion. Such queries now
issue a deprecation warning with the advice to add an <code class="docutils literal notranslate"><span class="pre">order_by()</span></code> to retain
the current query. <code class="docutils literal notranslate"><span class="pre">Meta.ordering</span></code> will be ignored in such queries starting
in Django 3.1.</p>
</div>
<div class="section" id="s-id2">
<span id="id2"></span><h3>Miscellaneous<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">django.utils.timezone.FixedOffset</span></code> is deprecated in favor of
<a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.timezone" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.timezone</span></code></a>.</li>
<li>The undocumented <code class="docutils literal notranslate"><span class="pre">QuerySetPaginator</span></code> alias of
<code class="docutils literal notranslate"><span class="pre">django.core.paginator.Paginator</span></code> is deprecated.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">FloatRangeField</span></code> model and form fields in <code class="docutils literal notranslate"><span class="pre">django.contrib.postgres</span></code>
are deprecated in favor of a new name, <code class="docutils literal notranslate"><span class="pre">DecimalRangeField</span></code>, to match the
underlying <code class="docutils literal notranslate"><span class="pre">numrange</span></code> data type used in the database.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">FILE_CHARSET</span></code> setting is deprecated. Starting with Django 3.1, files
read from disk must be UTF-8 encoded.</li>
<li><code class="docutils literal notranslate"><span class="pre">django.contrib.staticfiles.storage.CachedStaticFilesStorage</span></code> is
deprecated due to the intractable problems that it has. Use
<a class="reference internal" href="../ref/contrib/staticfiles.html#django.contrib.staticfiles.storage.ManifestStaticFilesStorage" title="django.contrib.staticfiles.storage.ManifestStaticFilesStorage"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManifestStaticFilesStorage</span></code></a> or a third-party cloud storage instead.</li>
<li><a class="reference internal" href="../ref/contrib/auth.html#django.contrib.auth.backends.RemoteUserBackend.configure_user" title="django.contrib.auth.backends.RemoteUserBackend.configure_user"><code class="xref py py-meth docutils literal notranslate"><span class="pre">RemoteUserBackend.configure_user()</span></code></a> is now passed <code class="docutils literal notranslate"><span class="pre">request</span></code> as the
first positional argument, if it accepts it. Support for overrides that don’t
accept it will be removed in Django 3.1.</li>
<li>The <a class="reference internal" href="../topics/testing/tools.html#django.test.SimpleTestCase.allow_database_queries" title="django.test.SimpleTestCase.allow_database_queries"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SimpleTestCase.allow_database_queries</span></code></a>,
<a class="reference internal" href="../topics/testing/tools.html#django.test.TransactionTestCase.multi_db" title="django.test.TransactionTestCase.multi_db"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TransactionTestCase.multi_db</span></code></a>, and <a class="reference internal" href="../topics/testing/tools.html#django.test.TestCase.multi_db" title="django.test.TestCase.multi_db"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TestCase.multi_db</span></code></a>
attributes are deprecated in favor of <a class="reference internal" href="../topics/testing/tools.html#django.test.SimpleTestCase.databases" title="django.test.SimpleTestCase.databases"><code class="xref py py-attr docutils literal notranslate"><span class="pre">SimpleTestCase.databases</span></code></a>,
<a class="reference internal" href="../topics/testing/tools.html#django.test.TransactionTestCase.databases" title="django.test.TransactionTestCase.databases"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TransactionTestCase.databases</span></code></a>, and <a class="reference internal" href="../topics/testing/tools.html#django.test.TestCase.databases" title="django.test.TestCase.databases"><code class="xref py py-attr docutils literal notranslate"><span class="pre">TestCase.databases</span></code></a>.
These new attributes allow databases dependencies to be declared in order to
prevent unexpected queries against non-default databases to leak state
between tests. The previous behavior of <code class="docutils literal notranslate"><span class="pre">allow_database_queries=True</span></code> and
<code class="docutils literal notranslate"><span class="pre">multi_db=True</span></code> can be achieved by setting <code class="docutils literal notranslate"><span class="pre">databases='__all__'</span></code>.</li>
</ul>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Django 2.2 release notes</a><ul>
<li><a class="reference internal" href="#python-compatibility">Python compatibility</a></li>
<li><a class="reference internal" href="#what-s-new-in-django-2-2">What’s new in Django 2.2</a><ul>
<li><a class="reference internal" href="#constraints">Constraints</a></li>
<li><a class="reference internal" href="#minor-features">Minor features</a><ul>
<li><a class="reference internal" href="#django-contrib-admin"><code class="docutils literal notranslate"><span class="pre">django.contrib.admin</span></code></a></li>
<li><a class="reference internal" href="#django-contrib-auth"><code class="docutils literal notranslate"><span class="pre">django.contrib.auth</span></code></a></li>
<li><a class="reference internal" href="#django-contrib-gis"><code class="docutils literal notranslate"><span class="pre">django.contrib.gis</span></code></a></li>
<li><a class="reference internal" href="#django-contrib-postgres"><code class="docutils literal notranslate"><span class="pre">django.contrib.postgres</span></code></a></li>
<li><a class="reference internal" href="#django-contrib-staticfiles"><code class="docutils literal notranslate"><span class="pre">django.contrib.staticfiles</span></code></a></li>
<li><a class="reference internal" href="#database-backends">Database backends</a></li>
<li><a class="reference internal" href="#generic-views">Generic Views</a></li>
<li><a class="reference internal" href="#internationalization">Internationalization</a></li>
<li><a class="reference internal" href="#management-commands">Management Commands</a></li>
<li><a class="reference internal" href="#migrations">Migrations</a></li>
<li><a class="reference internal" href="#models">Models</a></li>
<li><a class="reference internal" href="#requests-and-responses">Requests and Responses</a></li>
<li><a class="reference internal" href="#serialization">Serialization</a></li>
<li><a class="reference internal" href="#tests">Tests</a></li>
<li><a class="reference internal" href="#urls">URLs</a></li>
<li><a class="reference internal" href="#validators">Validators</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#backwards-incompatible-changes-in-2-2">Backwards incompatible changes in 2.2</a><ul>
<li><a class="reference internal" href="#database-backend-api">Database backend API</a></li>
<li><a class="reference internal" href="#admin-actions-are-no-longer-collected-from-base-modeladmin-classes">Admin actions are no longer collected from base <code class="docutils literal notranslate"><span class="pre">ModelAdmin</span></code> classes</a></li>
<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">django.contrib.gis</span></code></a></li>
<li><a class="reference internal" href="#transactiontestcase-serialized-data-loading"><code class="docutils literal notranslate"><span class="pre">TransactionTestCase</span></code> serialized data loading</a></li>
<li><a class="reference internal" href="#sqlparse-is-required-dependency"><code class="docutils literal notranslate"><span class="pre">sqlparse</span></code> is required dependency</a></li>
<li><a class="reference internal" href="#cached-property-aliases"><code class="docutils literal notranslate"><span class="pre">cached_property</span></code> aliases</a></li>
<li><a class="reference internal" href="#permissions-for-proxy-models">Permissions for proxy models</a></li>
<li><a class="reference internal" href="#merging-of-form-media-assets">Merging of form <code class="docutils literal notranslate"><span class="pre">Media</span></code> assets</a></li>
<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a></li>
</ul>
</li>
<li><a class="reference internal" href="#features-deprecated-in-2-2">Features deprecated in 2.2</a><ul>
<li><a class="reference internal" href="#model-meta-ordering-will-no-longer-affect-group-by-queries">Model <code class="docutils literal notranslate"><span class="pre">Meta.ordering</span></code> will no longer affect <code class="docutils literal notranslate"><span class="pre">GROUP</span> <span class="pre">BY</span></code> queries</a></li>
<li><a class="reference internal" href="#id2">Miscellaneous</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="2.2.1.html"
                        title="previous chapter">Django 2.2.1 release notes</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="2.1.15.html"
                        title="next chapter">Django 2.1.15 release notes</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/releases/2.2.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Mar 04, 2020</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="2.2.1.html" title="Django 2.2.1 release notes">previous</a>
     |
    <a href="index.html" title="Release notes" accesskey="U">up</a>
   |
    <a href="2.1.15.html" title="Django 2.1.15 release notes">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>